<?php
/**
 * Project: AIGC
 * Author: moufer <moufer@163.com>
 * Date: 2024/7/19 13:10
 */

namespace module\user\logic;

use module\user\enum\VipPeriodEnum;
use module\user\model\ScoreLog;
use module\user\model\User;
use module\user\model\VipLog;
use mof\annotation\Inject;
use mof\exception\LogicException;
use mof\Logic;
use mof\Model;

class UserLogic extends Logic
{
    #[Inject(User::class)]
    protected $model;

    /**
     * 当前操作的用户
     * @var User
     */
    protected User $user;

    public function withUser(User $user): static
    {
        $this->user = $user;
        return $this;
    }

    /**
     * 增加积分
     * @param int $score 积分
     * @param string $type 增加类型
     * @param string $remark 备注
     * @param string $module 涉及模块
     * @return ScoreLog
     */
    public function addScore(int $score, string $type, string $remark = '', string $module = 'user'): ScoreLog
    {
        $this->user->score += $score;
        //更新表
        $this->user->save();

        $data = [
            'score'   => $score,
            'flow'    => 'in',
            'type'    => $type,
            'remark'  => $remark,
            'module'  => $module,
            'user_id' => $this->user->id,
            'after'   => $this->user->score,
        ];
        return ScoreLog::create($data);
    }

    /**
     * 减少积分
     * @param int $score 积分
     * @param string $type 增加类型
     * @param string $remark 备注
     * @param string $module 涉及模块
     * @return ScoreLog
     */
    public function decScore(int $score, string $type, string $remark = '', string $module = 'user'): ScoreLog
    {
        $this->user->score -= $score;
        if ($this->user->score < 0) {
            throw new LogicException('用户积分不足', 1001);
        }
        //更新表
        $this->user->save();

        $data = [
            'score'   => $score,
            'flow'    => 'out',
            'type'    => $type,
            'remark'  => $remark,
            'module'  => $module,
            'user_id' => $this->user->id,
            'after'   => $this->user->score,
        ];
        return ScoreLog::create($data);
    }

    /**
     * vip升级
     * @param int $value 时间值
     * @param VipPeriodEnum $period
     * @param Model|null $order 订单信息
     * @param string|null $remark 备注
     * @return VipLog
     */
    public function upgradeVip(int    $value, VipPeriodEnum $period, Model $order = null,
                               string $remark = null): VipLog
    {
        $startDay = $this->user->vip_expire && strtotime($this->user->vip_expire) > time()
            ? strtotime($this->user->vip_expire)
            : time();

        //$startDay改为00:00:00
        $startDateTime = strtotime(date('Y-m-d', $startDay));
        $endDateTime = $period->getFutureTime($value, $startDateTime);

        $this->user->vip = 1;
        $this->user->vip_expire = date('Y-m-d', $endDateTime);
        $this->user->save();

        $data = [
            'user_id'    => $this->user->id,
            'type'       => 'upgrade',
            'begin_date' => date('Y-m-d', $startDateTime),
            'end_date'   => date('Y-m-d', $endDateTime),
            'order_id'   => $order?->id,
            'remark'     => $remark
        ];
        return VipLog::create($data);
    }

    /**
     * VIP降级
     * @param int $value 时间值
     * @param VipPeriodEnum $period 周期单位
     * @param Model|null $order 订单
     * @param string|null $remark 备注
     * @return VipLog
     */
    public function downgradeVip(int    $value, VipPeriodEnum $period, Model $order = null,
                                 string $remark = null): VipLog
    {
        if ($this->user->vip <= 0) {
            throw new LogicException('用户未开通会员', 1002);
        } else if (!$this->user->vip_expire) {
            throw new LogicException('用户会员期无效', 1003);
        }

        $current = strtotime(date('Y-m-d'));
        $time = strtotime($this->user->vip_expire);
        if ($time <= $current) {
            if ($this->user->vip !== -1) {
                $this->user->save(['vip' => -1]);
            }
            throw new LogicException('用户会员已过期', 1004);
        }

        $endDateTime = $period->getPastTime($value, $time);
        $this->user->vip_expire = date('Y-m-d', $endDateTime);
        $this->user->vip = $endDateTime > $current ? 1 : -1;
        $this->user->save();

        $data = [
            'user_id'    => $this->user->id,
            'type'       => 'downgrade',
            'begin_date' => date('Y-m-d', $time),
            'end_date'   => date('Y-m-d', $endDateTime),
            'order_id'   => $order?->id,
            'remark'     => $remark
        ];

        return VipLog::create($data);
    }
}